class_name Player
extends CharacterBody2D

## 球员角色
enum PlayerRole {
	## 守门员
	GOALIE,
	## 后卫
	DEFENSE,
	## 中场
	MIDFIELD,
	## 前锋
	OFFENSE
}

## 球员肤色
enum PlayerSkin {
	LIGHT, MEDIUM, DARK
}



## 球员的主客场
enum PlayerVenue {
	HOME, AWAY
}

enum PlayerSchema {
	P1, P2, CPU
}


const COUNTRIES := ["DEFAULT", "FRANCE", "ARGENTINA", "BRAZIL", "ENGLAND", "GERMANY", "ITALY", "SPAIN", "USA"]


const CONTROL_SPRITE_MAP :Dictionary[PlayerSchema, Texture2D] = {
	PlayerSchema.CPU: GlobalConstants.CPU_TEXTURE,
	PlayerSchema.P1: GlobalConstants.P1_TEXTURE,
	PlayerSchema.P2: GlobalConstants.P2_TEXTURE
}



const STATE_IDLE := "idle"
const STATE_RUN := "run"
const STATE_TACKLING := "tackling"
const STATE_RECOVERING := "recovering"
const STATE_PREPPING_SHOT := "preppingshot"
const STATE_SHOOTING := "shooting"
const STATE_PASSING := "passing"
const STATE_BICYCLE_KICK := "bicyclekick"
const STATE_VOLLEY_KICK := "volleykick"
const STATE_HEADER := "header"
const STATE_CHEST_CONTROL := "chestcontrol"


const ANIMATION_IDLE := "idle"
const ANIMATION_RUN := "run"
const ANIMATION_TACKLE := "tackle"
const ANIMATION_RECOVER := "recover"
const ANIMATION_PREP_KICK := "prep_kick"
const ANIMATION_KICK := "kick"
const ANIMATION_PASS := "pass"
const ANIMATION_BICYCLE_KICK := "bicycle_kick"
const ANIMATION_VOLLEY_KICK := "volley_kick"
const ANIMATION_HEADER := "header"
const ANIMATION_CHEST_CONTROL := "chest_control"



@onready var player_sprite: Sprite2D = $PlayerSprite
@onready var control_sprite: Sprite2D = $PlayerSprite/ControlSprite
@onready var animation_player: AnimationPlayer = $AnimationPlayer
@onready var teammate_detection_area: Area2D = $TeammateDetectionArea
@onready var ball_detection_area: Area2D = $BallDetectionArea
@onready var state_matchine: NodeStateMachine = $StateMachine


## 控制方案
@export var control_schema: PlayerSchema = PlayerSchema.P1
## 输入模式
@export var input_schema: InputManager.InputSchema = InputManager.InputSchema.P1
## 主场或客场
@export var venue: PlayerVenue


@export_group("Running")
## 奔跑速度
@export var speed: float = 80.0


@export_group("Tackling")
## 铲球速度
@export var tackling_speed: float = 100.0
## 铲球完成后准备进入恢复状态的时间（秒）
@export var duration_tackle_to_recover: float = 0.05


@export_group("Shooting")
## 射门力量
@export var shooting_power: float = 70.0
## 射门力量的缓动曲线
@export_exp_easing("positive_only") var bonus_curve: float = 2.0
## 最大的射门预备持续时间（秒）
@export var max_prepping_shot_bonus: float = 1.5
## 头球射门时力量的倍率
@export var header_power_factor: float = 1.5
## 凌空抽射时力量的倍率
@export var volley_kick_power_factor: float = 1.5
## 倒钩射门时力量的倍率
@export var bicycle_kick_power_factor: float = 1.5


## 恢复时间（秒），铲球、头球、凌空抽射等状态结束进入恢复状态后，在恢复状态中的持续时间
@export var duration_recover: float = 0.2


var input_manager: InputManager
## 球的引用，但是未必携带此球
var ball: Ball:
	get: return _ball
# 球，由 group 查找到，此变量不应该被直接使用，也不应该被设置为空值
var _ball: Ball

## 进攻的球门
var offensive_goal: Goal:
	get: return _offensive_goal
# 进攻的球门，由 group 查找到，不应该直接使用此变量
var _offensive_goal: Goal
## 防守的球门
var defensive_goal: Goal:
	get: return _defensive_goal
# 防守的球门，由 group 查找到，不应该直接使用此变量
var _defensive_goal: Goal

# 高度
var height: float = 0.0
# 高度速度
var height_velocity: float = 0.0

var player_full_name: String
var player_country: String = COUNTRIES[0]
var player_role: PlayerRole = PlayerRole.MIDFIELD
var player_skin: PlayerSkin = PlayerSkin.LIGHT



func _ready():
	input_manager = InputManager.new(input_schema)
	set_control_texture()
	set_control_texture_visible()
	_set_shader()

	await get_tree().process_frame
	_init_goals()
	_ball = Sundry.find_ball(get_tree())
	# 初始化球员朝向
	look_at_direction(offensive_goal.position - position)



func _process(_delta: float):
	input_manager.process_input()
	flip_sprite()
	set_control_texture_visible()


func _init_goals():
	var goals := Sundry.find_goals(get_tree())
	match venue:
		PlayerVenue.HOME:
			_offensive_goal = goals[Goal.GoalLocation.AWAY]
			_defensive_goal = goals[Goal.GoalLocation.HOME]
		PlayerVenue.AWAY:
			_offensive_goal = goals[Goal.GoalLocation.HOME]
			_defensive_goal = goals[Goal.GoalLocation.AWAY]


func _set_shader():
	var sprite_material := player_sprite.material as ShaderMaterial
	if not sprite_material:
		return
	var country_index := COUNTRIES.find(player_country)
	if country_index == -1:
		country_index = 0
	sprite_material.set_shader_parameter("team_color", country_index)
	sprite_material.set_shader_parameter("skin_color", player_skin)


## 初始化球员，由生成球员实例时调用
func initialize(context_position: Vector2, context_venue: PlayerVenue, context_resource: PlayerResource):
	position = context_position
	venue = context_venue
	speed = context_resource.speed
	shooting_power = context_resource.power
	player_full_name = context_resource.full_name
	player_country = context_resource.country
	player_role = context_resource.player_role
	player_skin = context_resource.player_skin

	# TODO 暂时将客场球员配置为 P2
	if context_venue == PlayerVenue.AWAY:
		control_schema = PlayerSchema.P2
		input_schema = InputManager.InputSchema.P2



func flip_sprite():
	if velocity.x > 0:
		player_sprite.flip_h = false
	elif velocity.x < 0:
		player_sprite.flip_h = true


# 角色朝向，1：右，-1：左
func character_orientation() -> int:
	if player_sprite.flip_h:
		return -1
	else:
		return 1

# 与 character_orientation 相同，返回的是 Vector2，其中 x 为方向，y 为 0
func character_direction() -> Vector2:
	return Vector2.RIGHT * character_orientation()


# 看向指定方向
func look_at_direction(direction: Vector2):
	if direction.x > 0:
		player_sprite.flip_h = false
	elif direction.x < 0:
		player_sprite.flip_h = true



# 是否携带球
func is_carrying_ball() -> bool:
	if not ball or not ball.carrier:
		return false
	return ball.carrier == self


# 设置显示控制者的图片
func set_control_texture():
	control_sprite.texture = CONTROL_SPRITE_MAP[control_schema]


func set_control_texture_visible():
	control_sprite.visible = is_carrying_ball() or control_schema != PlayerSchema.CPU



# 判断是否面向进攻的球迷
func is_facing_offensive_goal() -> bool:
	var direction_to_goal := position.direction_to(offensive_goal.position)
	return character_direction().dot(direction_to_goal) > 0


# 进入控球
func control_ball():
	state_matchine.transition_to(Player.STATE_CHEST_CONTROL)
